#pragma once

#include <list>
using std::list;

#include "Semaphore.h"
#include "Thread.h"
#include "Mutex.h"
#include "Condition.h"
#include "Semaphore.h"
#include "Job.h"

#include <iostream>
using namespace std;


class ThreadPool
{
public:
    ThreadPool(int nInitThreads, int nMaxThreads);
    ~ThreadPool(void);

    Thread* GetIdleThread();

    void CreateIdleThread(int nNumbers);
    void DeleteIdleThread(int nNumbers);

    bool RemoveThread(Thread* pThread);
    bool RemoveBusyThread(Thread* pThread);
    bool RemoveIdleThread(Thread* pThread);

    bool DeleteThread(Thread* pThread);
    bool DeleteBusyThread(Thread* pThread);
    bool DeleteIdleThread(Thread* pThread);

    void MoveToBusyList(Thread* pThread);
    void MoveToIdleList(Thread* pThread);

    int GetBusyThreadNumbers();
    int GetIdleThreadNumbers();

    int GetThreadNumbers();
    int GetMaxThreadNumbers();

    void StartAll();
    void TerminateAll();
    void DeleteAll();

    void Assign(Job* pJob);


private:
    int m_nThreads;
    int m_nMaxThreads;

    Semaphore m_semThreads;
    Semaphore m_semMaxThreads;

    list<Thread *> m_listBusy;
    list<Thread *> m_listIdle;

    Mutex m_mutexBusy; //when visit busy list,use m_mutexBusy to lock and unlock
    Mutex m_mutexIdle; //when visit idle list,use m_mutexIdle to lock and unlock

    Condition m_condBusy;
    Condition m_condIdle;
};

